iT邦幫忙

2024 iThome 鐵人賽

DAY 17
0

今天我們來看

abstract class Model

裡面到底是怎麼將對物件的存取轉換成對資料庫的存取的

Model 裡面 find() 的實作如下

/**
 * Find a model by its primary key.
 *
 * @param  mixed  $id
 * @param  array|string  $columns
 * @return ($id is (\Illuminate\Contracts\Support\Arrayable<array-key, mixed>|array<mixed>) ? \Illuminate\Database\Eloquent\Collection<int, TModel> : TModel|null)
 */
public function find($id, $columns = ['*'])
{
    if (is_array($id) || $id instanceof Arrayable) {
        return $this->findMany($id, $columns);
    }

    return $this->whereKey($id)->first($columns);
}

我們這邊先看 find() 輸入值為一個的狀況,所以會取用到 whereKey()

whereKey() 的實作則是

/**
 * Add a where clause on the primary key to the query.
 *
 * @param  mixed  $id
 * @return $this
 */
public function whereKey($id)
{
    if ($id instanceof Model) {
        $id = $id->getKey();
    }

    if (is_array($id) || $id instanceof Arrayable) {
        if (in_array($this->model->getKeyType(), ['int', 'integer'])) {
            $this->query->whereIntegerInRaw($this->model->getQualifiedKeyName(), $id);
        } else {
            $this->query->whereIn($this->model->getQualifiedKeyName(), $id);
        }

        return $this;
    }

    if ($id !== null && $this->model->getKeyType() === 'string') {
        $id = (string) $id;
    }

    return $this->where($this->model->getQualifiedKeyName(), '=', $id);
}

where() 則是

/**
 * Add a basic where clause to the query.
 *
 * @param  (\Closure(static): mixed)|string|array|\Illuminate\Contracts\Database\Query\Expression  $column
 * @param  mixed  $operator
 * @param  mixed  $value
 * @param  string  $boolean
 * @return $this
 */
public function where($column, $operator = null, $value = null, $boolean = 'and')
{
    if ($column instanceof Closure && is_null($operator)) {
        $column($query = $this->model->newQueryWithoutRelationships());

        $this->query->addNestedWhereQuery($query->getQuery(), $boolean);
    } else {
        $this->query->where(...func_get_args());
    }

    return $this;
}

這裡會使用到 $this->query$this->query 的型別是

/**
 * The base query builder instance.
 *
 * @var \Illuminate\Database\Query\Builder
 */
protected $query;

追到這邊我們會發現,Eloquent\Builder 到後面,底層依舊是使用 Query\Builder 進行實作的。

仔細想想也會發現這樣很合理,畢竟我們已經寫了一段生成 SQL Query 的邏輯,我們不需要重新再寫一次。只要讓 Model 裡面所使用的 Eloquent\Builder 包含 Query\Builder 即可。

剩下的部分,我們明天再來看!


上一篇
Day 16:DAO 轉換
下一篇
Day 18:ORM 的 where() 轉換
系列文
Laravel 那麼好用還需要自幹框架嗎18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言